﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WcfGeebaServer.Users;
using WcfGeebaServer.Logging;
using System.Data;

namespace WcfGeebaServer.DBDAL
{
    public class MemberDA
    {
        public static MemberDA getMemberDA()
        {
            return new MemberDA();
        }

        /// <summary>
        /// Add a member
        /// </summary>
        /// <param name="username">The username of the member</param>
        /// <param name="password">The password of the member</param>
        /// <returns>True if succeeds, else false</returns>
        public bool AddMember(string username, string password) {
            bool res = false;
            if (Data.members.Select("username = '" + username + "'").Length == 0)
            {
                if (Data.usersAdapter.Insert(username,password,true,UserType.Member.ToString(),false,false)==0)
                    return false;
                Data.members = Data.usersAdapter.GetMembers();
                
                res = true;
            }
            return res;
        }
        
        /// <summary>
        /// Remove a member
        /// </summary>
        /// <param name="username">The username of the member to remove</param>
        /// <returns>True if succeeds, else false</returns>
        public bool RemoveMember(string username) {
            
            GeebaDS.UsersRow user = Data.members.FindByusername(username);
            if (user != null)
            {
                user.Delete();
                Data.members.AcceptChanges();
                Data.usersAdapter.Update(Data.members);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Get the member with the username
        /// </summary>
        /// <param name="username">The username of the member to find</param>
        /// <returns>Member with the given username, null if not found</returns>
        public Member GetMember(string username)  {
            GeebaDS.UsersRow userRow = (GeebaDS.UsersRow) Data.members.Rows.Find(username);// FindByusername(username);
            if (userRow == null)
                return null;
            Member member = new Member(userRow.username, userRow.password, userRow.isActive);
            member.UserType = (UserType)Enum.Parse(typeof(UserType), userRow.userType, true);

            return member;
        }

        /// <summary>
        /// Get all members
        /// </summary>
        /// <returns>A list of all members</returns>
        public List<Member> GetMembers() {
            List<GeebaDS.UsersRow> list = Data.members.ToList();
            if(list.Count == 0)
                return null;

            List<Member> members = new List<Member>();
            Member member = null;
            foreach (GeebaDS.UsersRow row in list)
            {
                member =new Member(row.username,row.password,row.isActive);
                member.UserType = (UserType)Enum.Parse(typeof(UserType), row.userType, true);
                members.Add(member);
                
            }
            return members;
        }

        public bool changeMemberPassword(Member toChange, string newPass)
        {
            Data.members.FindByusername(toChange.Username).password = newPass;
            Data.members.AcceptChanges();
            Data.usersAdapter.Update(Data.members);
            return true;
        }

        public bool setInitialAdministrator(Member admin)
        {
            if (Data.usersAdapter.SetUserType(UserType.Admin.ToString(), 
                admin.Username, admin.Username) == 0)
            {
                return false;
            }

            Data.members = Data.usersAdapter.GetMembers();
            admin.UserType = UserType.Admin;
            Data.admin = admin;


            return true;
        }

        public bool replaceAdministrator(Member admin)
        {
            if (Data.admin == null)
                return setInitialAdministrator(admin);

            var count = (from mod in Data.moderators
                         where mod.username == Data.admin.Username
                         select mod).Count();

            UserType newType = UserType.Member;
            if (count > 0)
            {
                newType = UserType.Moderator;
            }

            if (Data.usersAdapter.SetUserType(newType.ToString(), 
                Data.admin.Username, Data.admin.Username) == 0)
            {
                return false;
            }

            if (Data.usersAdapter.SetUserType(UserType.Admin.ToString(),
               admin.Username, admin.Username) == 0)
            {
                return false;
            }

            Data.members = Data.usersAdapter.GetMembers();

            Data.admin = admin;
            return true;
        }

        public int getThreadCount(string username)
        {
            int res = (from row in Data.threads
                      where row.publishedBy == username
                      select row).Count();
            return res;
        }

        public bool isLawBreaker(string username)
        {
            return Data.members.FindByusername(username).isLawBreaker;
        }

        public bool setLawBreaker(string username,bool isLawBreaker)
        {
            if (Data.usersAdapter.SetLawBreaker(isLawBreaker,username,username) == 0)
            {
                return false;
            }

            Data.members = Data.usersAdapter.GetMembers();

            return true;
            
        }

        public bool setIsActive(string username, bool isActive)
        {
            if (Data.usersAdapter.setIsActive(isActive, username, username) == 0)
            {
                return false;
            }

            Data.members = Data.usersAdapter.GetMembers();

            return true;
        }

        public bool BanMember(string username)
        {
            if (Data.usersAdapter.SetBanned(true,username,username) == 0)
            {
                return false;
            }

            Data.members = Data.usersAdapter.GetMembers();

            return true;
        }

        public bool IsBanned(string username)
        {
            var query = (from member in Data.members
                         where member.username == username
                         select member.isBanned).Single();
            return query;
        }

        public UserType GetUserType(string username)
        {
            UserType result = UserType.Guest;

            var query = (from member in Data.members
                         where member.username == username
                         select member.userType);

            if (query.Count() == 0)
                return result;

            result = (UserType)Enum.Parse(typeof(UserType), query.Single(), true);

            if (result != UserType.Moderator && result != UserType.Admin)
            {
                var count = (from mod in Data.moderators
                             where mod.username == username
                             select mod).Count();

                if (count > 0)
                {
                    result = UserType.Moderator;
                }
            }

            return result;
        }
    }
}